package pl.edu.pk.psb.validator;

import static org.apache.commons.lang3.StringUtils.isAsciiPrintable;
import static org.apache.commons.lang3.StringUtils.isNumeric;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

import pl.edu.pk.psb.bc.util.Plec;
import pl.edu.pk.psb.command.UzytkownikCommand;

@Component
public class UzytkownikValidator extends OgolnyValidator implements Validator {

	@Autowired
	AdresValidator adresValidator;


	@Override
	public void validate(Object obiekt, Errors bledy) {
		UzytkownikCommand command = (UzytkownikCommand) obiekt;

		if (!czyPoprawnyString(command.getImie(),false)) {
			bledy.rejectValue("imie", "walidacja.niepoprawnaWartosc");
		}
		if (!czyPoprawnyString(command.getNazwisko(),false)) {
			bledy.rejectValue("nazwisko", "walidacja.niepoprawnaWartosc");
		}
		if (!czyPoprawnyString(command.getLogin(), 5, 20,true)) {
			bledy.rejectValue("login", "walidacja.loginZnaki");
		}
		if (!czyPoprawneHaslo(command.getHaslo())) {
			bledy.rejectValue("haslo", "walidacja.hasloZnaki");
		}
		if (!Plec.czyToPlec(command.getPlec())) {
			bledy.rejectValue("plec", "walidacja.wybracPlec");
		}
		if (!czyPoprawnyNumerTelefonu(command.getTelefon())) {
			bledy.rejectValue("telefon", "walidacja.niepoprawnyTelefon");
		}
		try {
			bledy.pushNestedPath("adres");
			ValidationUtils.invokeValidator(adresValidator, command.getAdres(), bledy);
		} finally {
			bledy.popNestedPath();
		}

	}

	/**
	 * Sprawdza czy haslo sklada sie od 5 do 20 znakow wlacznie i czy sklada sie
	 * ze znakow od kodu 32 do 126
	 * 
	 * @param tekst
	 *            do sprawdzenia
	 * @return true gdy spelnia zalozenia false w przeciwnym razie
	 */
	private boolean czyPoprawneHaslo(String haslo) {
		return haslo.length() >= 5 && haslo.length() <= 20 && isAsciiPrintable(haslo);
	}

	/**
	 * Sprawdza czy podany numer sklada sie od 9 do 15 cyfr
	 * 
	 * @param tekst
	 *            do sprawdzenia
	 * @return
	 */
	private boolean czyPoprawnyNumerTelefonu(String telefon) {
		return telefon.length() >= 9 && telefon.length() <= 15 && isNumeric(telefon);
	}

	@Override
	public boolean supports(Class<?> klasa) {
		return UzytkownikCommand.class.isAssignableFrom(klasa);
	}
}
